<script setup>
  import { nextTick, onBeforeUnmount, onMounted, ref } from 'vue'
  import {
    ArrowRight,
    Check,
    Clock,
    Close,
    Coin,
    Delete,
    Document,
    Download,
    Edit,
    FolderOpened,
    Share,
    View
  } from '@element-plus/icons-vue'
  import SvgIcon from '@/components/SvgIcon/SvgIcon.vue'
  import { getFileFontElement, shortName } from '@/utils/common.js'
  import { ElMessage, ElMessageBox } from 'element-plus'
  import Bus from '@/utils/bus.js'
  import { useUserStore } from '@/stores/modules/user.js'
  import { useFileStore } from '@/stores/modules/file.js'
  import {
    breadcrumbsService,
    createFolderService,
    fileListService,
    getDownloadUrlService,
    getPreviewUrlService,
    recycleFileService,
    renameService
  } from '@/api/file.js'
  import TransferDialog from '@/components/TransferDialog/TransferDialog.vue'
  import { downloadByUrl } from '@/utils/download.js'
  import TextPreview from '@/components/TextPreview/TextPreview.vue'
  import ImagePreview from '@/components/ImagePreview/ImagePreview.vue'
  import MiniAudioPlayer from '@/components/MiniAudioPlayer/MiniAudioPlayer.vue'
  import ShareDialog from '@/components/ShareDialog/ShareDialog.vue'

  const userStore = useUserStore()
  const fileStore = useFileStore()
  const fileList = ref([])
  const newFolderName = ref('')
  const isCreatingFolder = ref(false)
  const fileExtension = ref('')
  const newFolderInput = ref(null)
  const renameInput = ref(null)
  const showShareDialog = ref(false)

  // 右键菜单相关的响应式变量
  const showContextMenu = ref(false)
  const contextMenuX = ref(0)
  const contextMenuY = ref(0)
  const selectedFile = ref(null)

  const isRenaming = ref(false)
  const newFilename = ref('')
  const renamingFileId = ref(null)

  // 重命名相关方法
  const startRename = async file => {
    isRenaming.value = true
    renamingFileId.value = file.fileId

    // 如果是文件夹，直接使用完整文件名
    if (file.fileType === 0) {
      newFilename.value = file.filename
      fileExtension.value = ''
    } else {
      // 如果是文件，分离文件名和后缀
      const { name, extension } = splitFilename(file.filename)
      newFilename.value = name
      fileExtension.value = extension
    }

    selectedFile.value = null
    showContextMenu.value = false

    // 等待 DOM 更新后聚焦
    await nextTick()
    renameInput.value?.focus()
  }

  // 分离文件名和后缀
  const splitFilename = fullName => {
    const lastDotIndex = fullName.lastIndexOf('.')
    if (lastDotIndex === -1 || lastDotIndex === 0) {
      return {
        name: fullName,
        extension: ''
      }
    }
    return {
      name: fullName.substring(0, lastDotIndex),
      extension: fullName.substring(lastDotIndex)
    }
  }

  const handleRename = async () => {
    if (!newFilename.value.trim()) return ElMessage.warning('文件名称不能为空')
    // 构建完整的文件名（包含后缀）
    const fullFileName = fileExtension.value
      ? `${newFilename.value}${fileExtension.value}`
      : newFilename.value

    try {
      await renameService(renamingFileId.value, fullFileName)
      ElMessage.success('重命名成功')
      cancelRename()
      await getFileList()
    } catch (error) {
      console.error(error)
    }
  }

  const cancelRename = () => {
    isRenaming.value = false
    renamingFileId.value = null
    newFilename.value = ''
  }

  const handleRenameKeyup = event => {
    if (event.key === 'Enter') {
      handleRename()
    } else if (event.key === 'Escape') {
      cancelRename()
    }
  }

  // 调用上传组件并发送参数
  const upload = async () => {
    await ElMessageBox.confirm(`One File 最大支持同时上传15个文件`, '提示', {
      confirmButtonText: '继续',
      cancelButtonText: '取消',
      type: 'warning'
    })

    Bus.emit('openUploader', {
      options: {
        parentId: fileStore.parentId,
        userId: userStore.id
      }
    })
  }

  // 添加确认对话框方法
  const handleRecycleConfirm = async files => {
    // 立即隐藏右键菜单
    hideContextMenu()
    try {
      await ElMessageBox.confirm(
        files.length > 1
          ? `确认将这 ${files.length} 个文件放入回收站？`
          : `确认将 "${shortName(files[0].filename)}" 放入回收站？`,
        '提示',
        {
          confirmButtonText: '确认',
          cancelButtonText: '取消',
          type: 'warning'
        }
      )
      // 用户点击确认，执行回收站操作
      await handleRecycleFiles(files)
    } catch {
      // 用户点击取消，不执行任何操作
    }
  }

  // 文件放入回收站相关方法
  const handleRecycleFiles = async files => {
    try {
      const fileIds = files.map(file => file.fileId)
      await recycleFileService(fileIds)
      ElMessage.success(files.length > 1 ? '文件已批量放入回收站' : '文件已放入回收站')
      // 清空选择
      multipleSelection.value = []
      tableRef.value?.clearSelection()
      // 刷新文件列表
      await getFileList()
    } catch (error) {
      ElMessage.error('操作失败：' + (error.message || '未知错误'))
    }
  }

  const isLoading = ref(true)

  // 获取文件列表
  const getFileList = async () => {
    isLoading.value = true
    try {
      const res = await fileListService(fileStore.parentId)
      fileList.value = res.data
    } catch (error) {
      ElMessage.error('获取文件列表失败', error)
    } finally {
      isLoading.value = false
    }
  }

  const typeMatchingSvg = (filename, type) => {
    return getFileFontElement(filename, type)
  }

  // 新建文件夹相关方法
  const newFolder = async () => {
    if (isCreatingFolder.value) return
    isCreatingFolder.value = true
    fileList.value.unshift({
      fileId: 'temp',
      filename: '',
      fileType: 0,
      isNewFolder: true
    })
    // 等待 DOM 更新后聚焦
    await nextTick()
    newFolderInput.value?.focus()
  }

  const handleCreateFolder = async () => {
    if (!newFolderName.value.trim()) {
      ElMessage.warning('文件夹名称不能为空')
      return
    }

    try {
      await createFolderService(fileStore.parentId, newFolderName.value)
      ElMessage.success('创建成功')
      cancelCreateFolder()
      await getFileList()
    } catch (error) {
      ElMessage.error('创建失败', error)
    }
  }

  const cancelCreateFolder = () => {
    isCreatingFolder.value = false
    newFolderName.value = ''
    fileList.value = fileList.value.filter(item => !item.isNewFolder)
  }

  const handleFolderNameKeyup = event => {
    if (event.key === 'Enter') {
      handleCreateFolder()
    } else if (event.key === 'Escape') {
      cancelCreateFolder()
    }
  }

  // 左键双击预览
  const clickFile = row => {
    if (row.isNewFolder) return
    switch (row.fileType) {
      case 0: // 文件夹
        goInFolder(row.fileId)
        break
      case 3: // Word
      case 4: // Excel
      case 5: // PDF
      case 6: // 文本
      case 7: // 图片
      case 8: // 音频
      case 10: // PPT
      case 11: // 源码
        handlePreview(row)
        break
      default:
        ElMessage.warning('该文件类型暂不支持预览')
        break
    }
  }

  const goInFolder = async fileId => {
    try {
      isLoading.value = true
      const res = await breadcrumbsService(fileId)
      fileStore.clearBreadCrumbs()
      fileStore.setBreadCrumbs(res.data)
      fileStore.setParentId(fileId)
      await getFileList()
    } catch (error) {
      console.error('进入文件夹出错:', error)
    } finally {
      isLoading.value = false
    }
  }

  // 处理右键点击事件
  const handleContextMenu = (row, column, event) => {
    event.preventDefault()

    const isSelected = multipleSelection.value.some(item => item.fileId === row.fileId)

    if (!isSelected) {
      multipleSelection.value = []
      tableRef.value?.clearSelection()
      // 设置当前右键点击的行为选中状态
      tableRef.value?.toggleRowSelection(row, true)
      // 更新多选数组
      multipleSelection.value = [row]
    }

    selectedFile.value = row
    showContextMenu.value = true
    contextMenuX.value = event.clientX
    contextMenuY.value = event.clientY
  }

  // 右键菜单
  const handleMenuClick = async action => {
    // 保存当前选中的文件和多选数组
    const currentFile = selectedFile.value
    const currentSelection = [...multipleSelection.value]

    // 隐藏右键菜单
    hideContextMenu()

    switch (action) {
      case 'open':
        if (currentFile.fileType === 0) {
          await goInFolder(currentFile.fileId)
        }
        break
      case 'rename':
        await startRename(currentFile)
        break
      case 'preview':
        await handlePreview(currentFile)
        break
      case 'download':
        await handleDownloadFile({
          value: currentSelection
        })
        break
      case 'share':
        showShareDialog.value = true
        // ElMessage.warning('分享功能开发中')
        break
      case 'transfer':
        showTransferDialog.value = true
        break
      case 'recycle':
        await handleRecycleConfirm(currentSelection.length > 0 ? currentSelection : [currentFile])
        break
    }
  }

  // 隐藏右键菜单
  const hideContextMenu = event => {
    // 如果点击的是右键菜单内部的元素，不要立即隐藏（让点击事件先触发）
    if (event && event.target.closest('.context-menu')) {
      return
    }
    showContextMenu.value = false
    selectedFile.value = null
  }

  const handleTransferSuccess = async () => {
    multipleSelection.value = []
    tableRef.value?.clearSelection()
    await getFileList()
  }

  const goBack = () => {
    if (fileStore.breadCrumbs.length > 1) {
      let resolveBreadCrumbs = [...fileStore.breadCrumbs]
      resolveBreadCrumbs.pop()
      let newId = resolveBreadCrumbs.pop().id
      goToThis(newId)
    }
  }

  // 返回上一级
  const goToThis = async id => {
    if (id !== '-1') {
      try {
        isLoading.value = true
        let newBreadCrumbs = []
        fileStore.breadCrumbs.some(item => {
          newBreadCrumbs.push(item)
          if (item.id === id) {
            return true
          }
        })
        fileStore.setBreadCrumbs(newBreadCrumbs)
        fileStore.setParentId(id)
        await getFileList()
      } catch (error) {
        console.error('导航到文件夹出错:', error)
      } finally {
        isLoading.value = false
      }
    }
  }

  const multipleSelection = ref([])
  const handleSelectionChange = val => {
    multipleSelection.value = val
  }

  const tableRef = ref(null)

  const showTransferDialog = ref(false)

  const handleRowClick = (row, column) => {
    if (column) {
      // 如果点击的是复选框列，则不做任何处理
      if (column.type === 'selection') return

      // 清除之前的选择
      multipleSelection.value = []
      tableRef.value?.clearSelection()

      // 只选中当前行
      tableRef.value?.toggleRowSelection(row, true)
      multipleSelection.value = [row]
    }
  }

  // 文件下载
  const handleDownloadFile = async multipleSelection => {
    if (!multipleSelection?.value?.length) return

    if (multipleSelection.value.length > 1) {
      return ElMessage.warning('批量下载功能开发中')
    }

    const file = multipleSelection.value[0]
    if (!file) return

    if (file.fileType === 0) {
      return ElMessage.warning('文件夹不支持下载')
    }

    try {
      await ElMessageBox.confirm(`是否确认下载文件：${shortName(file.filename)}`, '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      })

      const res = await getDownloadUrlService(file.fileId)
      await downloadByUrl(res.data, file.filename)
      ElMessage.success('下载成功')
    } catch (error) {
      if (error !== 'cancel') {
        ElMessage.error('下载失败')
        console.error('Download failed:', error)
      }
    }
  }

  // 添加预览相关的响应式变量
  const imagePreviewVisible = ref(false)
  const audioPreviewVisible = ref(false)
  const previewFileUrl = ref('')
  const audioFileUrl = ref('') // 音频文件专用 URL
  const previewFileName = ref('')
  const audioFileName = ref('') // 音频文件专用文件名
  const previewFileSize = ref(0)
  const textPreviewVisible = ref(false)

  const handlePreview = async file => {
    try {
      // 获取预览URL
      const res = await getPreviewUrlService(file.fileId)
      if (file.fileType === 8) {
        // 音频文件
        audioFileUrl.value = res.data
        audioFileName.value = file.filename
        audioPreviewVisible.value = true
      } else {
        // 设置通用预览参数
        previewFileUrl.value = res.data
        previewFileName.value = file.filename
        previewFileSize.value = file.fileSize || 0

        switch (file.fileType) {
          case 3: // Word
          case 4: // Excel
          case 10: // PPT
            // 在新的浏览页中打开 Office 文档
            window.open(
              `https://view.officeapps.live.com/op/embed.aspx?src=${encodeURIComponent(previewFileUrl.value)}`,
              '_blank'
            )
            break
          case 5: // PDF
            // 在新的浏览页中打开pdf
            window.open(previewFileUrl.value, '_blank')
            break
          case 6: // 文本
          case 11: // 源码
            textPreviewVisible.value = true
            break
          case 7: // 图片
            imagePreviewVisible.value = true
            break
        }
      }
    } catch (error) {
      console.error('Preview failed:', error)
    }
  }

  // 判断是否需要显示tooltip
  const needTooltip = fileName => {
    return shortName(fileName) !== fileName
  }

  onMounted(async () => {
    await getFileList()

    // 禁用浏览器后退
    history.pushState(history.state, '', location.href)
    window.addEventListener('popstate', () => {
      history.pushState(history.state, '', location.href)
    })

    // 其他原有的事件监听
    document.addEventListener('click', hideContextMenu)
    Bus.on('uploadFileSuccess', () => {
      getFileList()
    })
  })

  onBeforeUnmount(() => {
    document.removeEventListener('click', hideContextMenu)
    window.removeEventListener('popstate', () => {})
  })
</script>

<template>
  <div class="page page-home">
    <!--控件-->
    <div class="btn-group">
      <el-button plain type="primary" @click="upload">上传</el-button>
      <el-button plain type="primary" @click="newFolder">新建文件夹</el-button>
    </div>
    <!-- TransferDialog -->
    <TransferDialog
      v-model="showTransferDialog"
      :files="multipleSelection.length > 0 ? multipleSelection : [selectedFile]"
      class="no-select"
      @success="handleTransferSuccess"
      @contextmenu.prevent
    />
    <!-- 文件列表 -->
    <el-card class="file-box no-select" @contextmenu.prevent>
      <div class="breadcrumb-content">
        <el-breadcrumb style="display: inline-block">
          <el-breadcrumb-item>
            <a class="breadcrumb-item-a" href="#" @click="goBack">
              <SvgIcon height="24px" name="file-type-back" width="24px" />
            </a>
          </el-breadcrumb-item>
        </el-breadcrumb>
        <el-divider direction="vertical" style="vertical-align: top !important" />
        <el-breadcrumb :separator-icon="ArrowRight" style="display: inline-block">
          <el-breadcrumb-item v-for="(item, index) in fileStore.breadCrumbs" :key="index">
            <a class="breadcrumb-item-a" href="#" @click="goToThis(item.id)">{{ item.name }}</a>
          </el-breadcrumb-item>
        </el-breadcrumb>
      </div>
      <el-scrollbar height="500px">
        <el-table
          ref="tableRef"
          v-loading="isLoading"
          :data="fileList"
          :row-style="{ height: '40px' }"
          element-loading-background="rgba(255, 255, 255, 0.9)"
          element-loading-text="数据加载中..."
          style="width: 100%; margin-top: 18px; cursor: pointer"
          @row-contextmenu="handleContextMenu"
          @selection-change="handleSelectionChange"
          @row-click="handleRowClick"
          @row-dblclick="clickFile"
          @contextmenu.prevent
        >
          <template #empty>
            <el-empty description="暂无文件" />
          </template>
          <el-table-column type="selection" width="35" />
          <el-table-column label="文件名" min-width="40%">
            <template #header>
              <div style="display: flex; align-items: center">
                <el-icon style="font-size: 16px; margin-right: 5px">
                  <Document />
                </el-icon>
                <span>文件名</span>
              </div>
            </template>
            <template #default="scope">
              <div style="display: flex; align-items: center">
                <template v-if="scope.row.isNewFolder">
                  <div class="folder-input-wrapper">
                    <el-input
                      ref="newFolderInput"
                      v-model="newFolderName"
                      autofocus
                      placeholder="请输入文件夹名称"
                      style="margin-left: 10px"
                      @keyup="handleFolderNameKeyup"
                    />
                    <div class="folder-actions">
                      <el-button class="action-btn" link type="primary" @click="handleCreateFolder">
                        <el-icon>
                          <Check />
                        </el-icon>
                      </el-button>
                      <el-button class="action-btn" link type="danger" @click="cancelCreateFolder">
                        <el-icon>
                          <Close />
                        </el-icon>
                      </el-button>
                    </div>
                  </div>
                </template>
                <template v-else-if="isRenaming && scope.row.fileId === renamingFileId">
                  <SvgIcon
                    :name="typeMatchingSvg(scope.row.filename, scope.row.fileType)"
                    height="24px"
                    width="24px"
                  />
                  <div class="folder-input-wrapper">
                    <div
                      class="rename-input-group"
                      style="display: flex; align-items: center; margin-left: 10px"
                    >
                      <el-input
                        ref="renameInput"
                        v-model="newFilename"
                        :placeholder="
                          scope.row.fileType === 0 ? '请输入文件夹名称' : '请输入文件名'
                        "
                        autofocus
                        style="flex: 1"
                        @keyup="handleRenameKeyup"
                      />
                      <span
                        v-if="fileExtension"
                        class="file-extension"
                        style="margin-left: 2px; color: #666"
                      >
                        {{ fileExtension }}
                      </span>
                    </div>
                    <div class="folder-actions">
                      <el-button class="action-btn" link type="primary" @click="handleRename">
                        <el-icon>
                          <Check />
                        </el-icon>
                      </el-button>
                      <el-button class="action-btn" link type="danger" @click="cancelRename">
                        <el-icon>
                          <Close />
                        </el-icon>
                      </el-button>
                    </div>
                  </div>
                </template>
                <template v-else>
                  <div class="file-item">
                    <SvgIcon
                      :name="typeMatchingSvg(scope.row.filename, scope.row.fileType)"
                      height="24px"
                      width="24px"
                    />
                    <span
                      :title="needTooltip(scope.row.filename) ? scope.row.filename : ''"
                      class="filename"
                    >
                      {{ shortName(scope.row.filename) }}
                    </span>
                  </div>
                </template>
              </div>
            </template>
          </el-table-column>
          <el-table-column align="center" label="修改时间" min-width="20%" prop="updateTime">
            <template #header>
              <div class="my-column">
                <el-icon style="font-size: 16px; margin-right: 5px">
                  <Clock />
                </el-icon>
                <span>修改时间</span>
              </div>
            </template>
          </el-table-column>
          <el-table-column align="center" label="大小" min-width="10%" prop="fileSizeDesc">
            <template #header>
              <div class="my-column">
                <el-icon style="font-size: 16px; margin-right: 5px">
                  <Coin />
                </el-icon>
                <span>大小</span>
              </div>
            </template>
          </el-table-column>
        </el-table>
      </el-scrollbar>
    </el-card>
    <!-- 文本预览组件 -->
    <TextPreview
      v-model="textPreviewVisible"
      :file-name="previewFileName"
      :file-url="previewFileUrl"
    />
    <!-- 图片预览组件 -->
    <ImagePreview
      v-model="imagePreviewVisible"
      :file-name="previewFileName"
      :file-url="previewFileUrl"
      @download="handleDownloadFile(selectedFile)"
    />
    <!-- 音频预览组件 -->
    <MiniAudioPlayer
      v-model="audioPreviewVisible"
      :file-name="audioFileName"
      :file-url="audioFileUrl"
    />
    <!--分享对话框 -->
    <ShareDialog
      :files="multipleSelection.length > 0 ? multipleSelection : [selectedFile]"
      :model-value="showShareDialog"
      class="no-select"
      @update:model-value="showShareDialog = $event"
      @contextmenu.prevent
    />

    <!-- 右键菜单 -->
    <div
      v-show="showContextMenu"
      :style="{ top: contextMenuY + 'px', left: contextMenuX + 'px' }"
      class="context-menu no-select"
      @contextmenu.prevent
    >
      <template v-if="selectedFile">
        <div class="menu-item" @click="handleMenuClick('rename')">
          <el-icon>
            <Edit />
          </el-icon>
          <span>重命名</span>
        </div>

        <!-- 文件夹只显示打开选项 -->
        <div v-if="selectedFile.fileType === 0" class="menu-item" @click="handleMenuClick('open')">
          <el-icon>
            <FolderOpened />
          </el-icon>
          <span>打开</span>
        </div>

        <!-- 其他类型文件显示全部选项 -->
        <template v-else>
          <div class="menu-item" @click="handleMenuClick('preview')">
            <el-icon>
              <View />
            </el-icon>
            <span>预览</span>
          </div>
          <div class="menu-item" @click="handleMenuClick('download')">
            <el-icon>
              <Download />
            </el-icon>
            <span>下载</span>
          </div>
          <div class="menu-item" @click="handleMenuClick('share')">
            <el-icon>
              <Share />
            </el-icon>
            <span>分享</span>
          </div>
        </template>

        <!-- 所有类型都显示移动和回收站选项 -->
        <div class="menu-item" @click="handleMenuClick('transfer')">
          <el-icon>
            <FolderOpened />
          </el-icon>
          <span>移动到</span>
        </div>
        <div class="menu-item" @click="handleMenuClick('recycle')">
          <el-icon>
            <Delete />
          </el-icon>
          <span>放入回收站</span>
        </div>
      </template>
    </div>
  </div>
</template>

<style lang="less" scoped>
  @import '@/assets/variable.less';

  .el-table {
    position: relative;
    min-height: 200px;
  }

  .file-item {
    display: flex;
    align-items: center;
    width: 100%;

    .filename {
      margin-left: 10px;
      line-height: 24px;
      display: inline-block;
      max-width: 500px;
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;
    }
  }

  .page-home {
    height: 100%;
  }

  .folder-input-wrapper {
    display: flex;
    align-items: center;
    width: 300px;

    .folder-actions {
      display: flex;
      align-items: center;
      margin-left: 8px;

      .action-btn {
        padding: 4px 8px;
        font-size: 16px;
      }
    }
  }

  .file-box {
    max-height: 620px;
    position: relative;
    margin-top: 20px;
    padding: 20px;
    flex: 1;
    background-color: #fff;

    .breadcrumb-content {
      display: flex;
      align-items: center;
      width: 100%;

      .breadcrumb-item-a {
        cursor: pointer !important;
        color: #409eff !important;
      }
    }

    .folder-input-wrapper {
      display: flex;
      align-items: center;
      width: 300px;

      .folder-actions {
        display: flex;
        align-items: center;
        margin-left: 8px;
        font-size: 20px;

        .action-btn {
          padding: 4px 8px;
          font-size: 20px;
        }
      }
    }
  }
</style>
